package components.tree;

import iso.ISOBurn;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.border.BevelBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import components.JDErrorDialog;
import components.JDVerticalFlowLayout;

public class DialogBurnIso extends JDialog {
	private static final long serialVersionUID = 1L;

	private TreeFile tree;
	private CheckTreeManager checkTreeManager;

	private JPanel panelPreview = new JPanel(new BorderLayout());
	private JPanel panelEast = new JPanel(new JDVerticalFlowLayout(JDVerticalFlowLayout.TOP, 4, 4, true, false));
	private JLabel label = new JLabel();
	private JButton btnCancel = new JButton("Cancel");
	private JButton btnBurn = new JButton("Burn");
	private JButton btnSaveIso = new JButton("Save ISO");

	public DialogBurnIso(File rootFile) {
		getContentPane().setLayout(new BorderLayout());
		setModal(true);
		setSize(new Dimension(800, 600));
		setLocationRelativeTo(null);

		tree = new TreeFile(rootFile);

		tree.expandAll();

		getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
		getContentPane().add(panelEast, BorderLayout.EAST);

		checkTreeManager = new CheckTreeManager(tree);

		btnCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});

		btnBurn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				burn();
			}
		});

		btnBurn.setEnabled(false);
		btnSaveIso.setEnabled(false);

		checkTreeManager.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent e) {
				nodeSelected();
			}
		});

		tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent e) {
				nodeSelected();
			}
		});

		btnSaveIso.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				saveIso();
			}
		});

		this.panelPreview.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
		this.label.setPreferredSize(new Dimension(200, 250));

		panelPreview.add(label, BorderLayout.CENTER);

		panelEast.add(panelPreview);
		panelEast.add(new JSeparator());
		panelEast.add(btnSaveIso);
		panelEast.add(btnBurn);
		panelEast.add(new JSeparator());
		panelEast.add(btnCancel);

		nodeSelected();

	}

	public void setSelecteds(File... files) {

		for (File file : files) {
			TreePath treePath = tree.find(file);
			if (treePath != null) {
				checkTreeManager.getSelectionModel().addSelectionPath(treePath);
			}
		}

	}

	private void nodeSelected() {
		try {

			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

			boolean enabled = checkTreeManager.getSelectionModel().getSelectionCount() > 0;
			
			btnBurn.setEnabled(enabled);
			btnSaveIso.setEnabled(enabled);

			TreePath selectionPath = tree.getSelectionPath();

			File file = tree.getFile(selectionPath);

			ImageIcon imageIcon = createImageIcon(file);

			label.setIcon(imageIcon);

		} catch (Exception e) {
			JDErrorDialog.reportException(e);
		} finally {
			setCursor(null);
		}
	}

	private List<File> getSelectedFiles(){
		TreePath[] selectionPaths = checkTreeManager.getSelectionModel().getSelectionPaths();

		return tree.getFile(selectionPaths);
		
	}
	
	public void burn() {

		File temp = null;

		try {

			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

			List<File> files = getSelectedFiles();
			
			if (files == null || files.isEmpty()) {
				JOptionPane.showMessageDialog(this, "No Files Selected.");
				return;
			}

			temp = getTempIsoFile();

			ISOBurn isoBurn = new ISOBurn(temp, files);

			isoBurn.process(getUserName(), "dicom");

			System.out.println("Iso File: " + temp);

		} catch (Exception e) {
			JDErrorDialog.reportException(e);
		} finally {
			setCursor(null);
		}
	}

	private void saveIso() {

		List<File> files = getSelectedFiles();
		
		if (files == null || files.isEmpty()) {
			JOptionPane.showMessageDialog(this, "No Files Selected.");
			return;
		}
		
		JFileChooser fileChooser = new JFileChooser();
		
		fileChooser.setSelectedFile(new File("dicom.iso"));
		
		if(fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION){
			return;
		}
		
		File temp = fileChooser.getSelectedFile();
		
		try {

			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			
			ISOBurn isoBurn = new ISOBurn(temp, files);

			isoBurn.process(getUserName(), "dicom");

			System.out.println("Iso File: " + temp);

		} catch (Exception e) {
			JDErrorDialog.reportException(e);
		} finally {
			setCursor(null);
		}

	}

	private ImageIcon createImageIcon(File file) throws IOException {

		ImageIcon imageIcon = null;

		if (file != null && file.isFile()) {

			BufferedImage image = ImageIO.read(file);

			if (image != null) {

				image = resizeImage(image, label.getSize().width, label.getSize().height);

				imageIcon = new ImageIcon(image);
			}
		}

		return imageIcon;
	}

	public BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {

		int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
		BufferedImage resizedImage = new BufferedImage(width, height, type);
		Graphics2D g = resizedImage.createGraphics();
		g.drawImage(originalImage, 0, 0, width, height, null);
		g.dispose();

		return resizedImage;
	}

	private String getUserName() {
		return System.getProperty("user.name");
	}

	private File getTempIsoFile() {

		File tempDir = new File("temp");

		tempDir.mkdirs();

		File tempFile = new File(tempDir, "dicom.iso");

		tempFile.deleteOnExit();

		return tempFile;
	}

	public static void main(String[] args) {
		DialogBurnIso frame = new DialogBurnIso(new File("C:/temp"));

		frame.setVisible(true);

		System.exit(0);
	}
}
